﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Dispatcher;
using System.Collections;
using Ngilead.Common;
using BusinessModel.Services.Interfaces;

namespace Annuaire.Web.Services.Behaviour
{
    public delegate T CloneOrMergeFunction<T>(T obj);

    public class NGileadOperationInvoker : IOperationInvoker
    {
        private IOperationInvoker InnerOperationInvoker;

        private IUtility _Utils;

        public NGileadOperationInvoker(IOperationInvoker operationInvoker, IUtility utils)
        {
            _Utils = utils;
            this.InnerOperationInvoker = operationInvoker;
        }

        #region IOperationInvoker Members

        public object[] AllocateInputs()
        {
            return InnerOperationInvoker.AllocateInputs();
        }

        public object Invoke(object instance, object[] inputs, out object[] outputs)
        {

            inputs = NGileadMergeOrClone(inputs, _Utils.BeanManager.Merge<object>) as object[];
            //If we receaive NGilead objects, merge them.
            object temp = InnerOperationInvoker.Invoke(instance, inputs, out outputs);

            //If it is NGilead objects, clone them.
            return NGileadMergeOrClone(temp, _Utils.BeanManager.Clone<object>);
        }


        public object NGileadMergeOrClone(object o, CloneOrMergeFunction<object> function)
        {
            return function(o);
        }

        public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
            return InnerOperationInvoker.InvokeBegin(instance, inputs, callback, state);
        }

        public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            return InnerOperationInvoker.InvokeEnd(instance, out outputs, result);
        }

        public bool IsSynchronous
        {
            get { return InnerOperationInvoker.IsSynchronous; }
        }

        #endregion
    }
}